package com.cw.exception.callback.impl;

import java.util.Map;

import com.alibaba.csp.sentinel.util.StringUtil;
import com.cw.framework.handle.DubboGenericServiceHandle;
import com.cw.starter.common.util.GsonUtil;
import org.apache.dubbo.rpc.service.GenericService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import com.cw.exception.callback.api.ExceptionCallbackApi;
import com.cw.exception.callback.dto.ExceptionCallbackReqDto;
import com.cw.exception.callback.dto.ExceptionCallbackRespDto;
import com.cw.exception.callback.enums.EnumExceptionCallbackTradeType;

/**
 * 异常回调实现类
 *
 * @author chenw
 */
public class ExceptionCallbackApiImpl implements ExceptionCallbackApi {
    private static final Logger logger = LoggerFactory.getLogger(ExceptionCallbackApiImpl.class);
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private DubboGenericServiceHandle dubboGenericServiceHandle;
    /**
     * http接口异常回调
     *
     * @param reqDto
     * @return
     */
    @Override
    public ExceptionCallbackRespDto cloudExceptionCallback(ExceptionCallbackReqDto reqDto) {
        logger.info("http回调请求参数:{}", GsonUtil.objectToJsonString(reqDto));
        //设置header信息
        HttpHeaders headers = new HttpHeaders();
        HttpMethod httpMethod = HttpMethod.resolve(reqDto.getHttpMethod()
            .toUpperCase());
        HttpEntity<ExceptionCallbackReqDto> entity = new HttpEntity<>(reqDto, headers);
        EnumExceptionCallbackTradeType tradeType = reqDto.getTradeType();
        ResponseEntity response;
        // cloud回调
        String requestUrl = reqDto.getInterfacePath();
        if (EnumExceptionCallbackTradeType.CLOUD == tradeType) {
            requestUrl = "http://" + reqDto.getApplicationName() + reqDto.getInterfacePath();
            response = restTemplate.exchange(requestUrl, httpMethod,entity,Map.class);
            logger.info("cloud服务回调响应:{}", GsonUtil.objectToJsonString(response));
        }else{
            RestTemplate httpRestTemplate = new RestTemplate();
            response = httpRestTemplate.exchange(requestUrl, httpMethod,entity,Map.class);
            logger.info("restful回调响应:{}", GsonUtil.objectToJsonString(response));
        }
        return ExceptionCallbackRespDto.builder().success(true).build();
    }

    /**
     * dubbo异常回调
     *
     * @param reqDto
     * @return
     */
    @Override
    public ExceptionCallbackRespDto dubboExceptionCallback(ExceptionCallbackReqDto reqDto) {

        logger.info("dubbo异常回调请求参数:{}", GsonUtil.objectToJsonString(reqDto));
        GenericService query = dubboGenericServiceHandle.getGenericService(reqDto.getApplicationName(), reqDto.getInterfaceName(),
            reqDto.getInterfaceVersion());
        Map paramMap = GsonUtil.json2Obj(GsonUtil.objectToJsonString(reqDto), Map.class);
        Object object;
        if (StringUtil.isBlank(reqDto.getInterfaceParamNames())) {
            object = query.$invoke(reqDto.getInterfaceMethod(), new String[] {reqDto.getClass().getName()},
                new Object[] {paramMap});
        } else {
            object = query.$invoke(reqDto.getInterfaceMethod(), reqDto.getInterfaceParamNames()
                .split(","), new Object[] {paramMap});
        }
        logger.info("dubbo回调响应:{}", GsonUtil.objectToJsonString(object));
        return ExceptionCallbackRespDto.builder().success(true).build();
    }
}
